\documentclass{report}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[francais]{babel}
\usepackage{graphicx}
\usepackage{enumerate}


\begin{document}

\title{
	\normalsize{ENSEIRB-MATMECA \\ 
	2011 - 2012} \\
	\vspace{15mm}
	\Huge{Projet Compilation: Partie Back-End}
} 
\author{Damien FERRY\\Arnaud GUILLOU\\Vincent LOUBET\\Mathilde OUSTLANT\\Clément SAVIGNY}

\date{
	\normalsize{Enseignants encadrants : Denis BARTHOU\\ Bertrand PUTIGNY}
}

\maketitle



\clearpage


\tableofcontents
\clearpage




\chapter*{Introduction}
  Cette partie du projet porte sur la réalisation du back-end prenant en entrée du code 2-adresses généré par le front-end et renvoyant du code assembleur qui sera par la suite compilé par gcc pour donné un exécutable. Cela a nécessité la mise en place d'une table des symboles servant à la gestion de la pile.


\chapter{Modélisation table des symboles}

La table des symboles est un élément indispensable à la structuration du back-end. Elle permet de retrouver de manière générique les adresses des variables ainsi que de conaître leurs types, elle doit donc être bien structurée afin d'en permettre une utilisation efficace.

\section{La structure declarator}

\subsection{La structure taille}

\subsection{La sructure declarator\_list}

\section{La structure table\_symbole}

\subsection{La structure symb} 

\section{Tableau général des structures}

\begin{figure}[position]
\begin{center}
   \caption{Schéma des structures de la table de symboles}
   \includegraphics[scale=0.43,angle=90]{structurestabsymb.jpg}
\end{center}
\end{figure}

\chapter{Mise en place de la pile}

La gestion de la pile est l'élément central du back-end, ceci ne peut être fait qu'avec un table de symboles bien structurée.

\begin{figure}[position]
\begin{center}
   \caption{Schéma de l'espace des addresses du programme}
   \includegraphics[scale=0.43]{addrspace.jpg}
\end{center}
\end{figure}


\chapter{Fonction}
\section{Déclaration d'une fonction}


Lors de la définition d'une fonction on commence par créer la table des symboles des paramètres de la fonction puis on ajoute les variables dans la table des symboles après avoir calculé l'offset d'incrémentation nécessaire (par rapport au BASE POINTER du bloc d'instruction de la fonction).

Ensuite on ajoute le symbole de la fonction dans la table des symboles globale et on initialise le pointeur vers la table des symbole des paramètre définie précedemment.

Enfin on écrit le label (qui sera le nom de la fonction) en ASM.

\section{Interprétation du corp de la fonction}

De manière générale lorsque l'on interprète le corp d'une fonction vu qu'elle commence toujours par un { et fini par un }, elle sera traitée exactement comme un bloc d'instructions. 

Donc lorsque l'on rencontre des chevrons que ce soit pour une fonction ou un bloc d'instruction dans  son corp on réalisera les étapes suivantes:
\begin{itemize}
\item empilement de l'adresse du BASE POINTER puis définition du BASE POINTER comme le STACK POINTER actuel.
\item création de la table des symboles locale au bloc d'instructions.
\item définition de la table de symbole current comme la table qui vient d'être créée.
\item ajout des symboles dans la table current avec calcul de l'offset par rapport au BASE POINTER local et écriture des commandes d'ajout à la pile (en ASM).
\item écriture des opérations sur les variables à l'intérieur du bloc(en ASM). Si on rencontre une commande return on écrit la valeur de retour dans \%eax.
\item définition du STACK POINTER commme le BASE POINTER (en ASM) et Définition du BASE POINTER comme le BASE POINTER précédent (en ASM) se trouvant à l'adresse mémoire supérieure.
\item écriture de la commande de retour sub-routine en ASM.
\end{itemize}

\section{Appel à une fonction}

Lors de l'appel d'une fonction(ex: f(a,b) avec f prenant en entrée un entier a et l'adresse d'un tableau b), on commence par empiler les paramètres(valeur de a et adresse de b) puis on fait un call de l'identifiant(ici f). Si la fonction renvoie un int alors on peut récupérer le résultat renvoyé dans \%eax.  

\chapter{Création d'une variable}

La création d'une variable se distinguera en 3 types, les paramètres d'entrée d'une fonction, les variables globales et les variables locales.

\section{Variable globale}

%la première table est créée en variable globale du fichier yacc
%ajout dans la table current avec calcul de l'offset
%empilement dans la pile

\section{Variable locale}

%création de la table si pas de table déjà créée pour le bloc d'instructions
%ajout à la table  de symboles et calcul de l'offset par rapport au base pointerde début de ce bloc
%création de la commande d'ajout à la pile lors de l'appel de la fonction

\section{Paramètre d'une fonction}

%création de la table si pas de table déjà créée pour les paramètres de la fonction
%ajout à la table  de symboles et calcul de l'offset par rapport au base pointer de début de la fontion idem que bloc mais au lieu de décrémenter par rapport au BP on incrémente
%création de la commande d'ajout à la pile lors de l'appel de la fonction





\chapter{Opération sur des variables}

Les opérations sur les variables se feront en deux étapes d'abord la recherche de l'adresse de la variable puis la création de la commande d'opération en assembleur. 

\section{Récupération de l'adresse de la variable dans la pile}

%recherche de l'offset dans les var locales puis paramètres puis globale calcul de l'adresse en fonction de l'offset trouvée et l'ebp de l'endroit où on se trouve.

On chargera la valeur de l'adresse mémoire ainsi trouvée dans un registre.

\section{Création de la commande d'opération}
On distinguera les opérations de comparaisons des opérations de modification de la valeur d'une variable.
\subsection{Opération de comparaison}
%sûrement explication du if en même temps

Nous avons effectuée diverses modification sur la grammaire en ce qui concerne les
instructions conditionnelles et les boucles. Nous avons donc choisi de représenter:

\begin{verbatim}
IF ( comparison_expression ) statement
\end{verbatim}  
par : 
\begin{verbatim}
if: comparison_expression 
then: statement
jmp endif
endif:
\end{verbatim}

Avant, de pouvoir exécuter cette expression sémantique, on exécute d'abord les expressions sémantiques de $$comparison\_expression$$ et $$statement$$. C'est pourquoi, pour pouvoir imbriquer les commandes relatives à ces expressions, nous avons du stocker les données dans une structure $$ret$$, composée des commandes $$cmd$$ relatives à chaque comparaison et statement et leurs répertoires où étés stockés leur valeur $$val$$.

Concernant les commandes de $$comparison\_expression$$, nous comparons d'abord les deux répertoires concernés, si nous obtenons la négation du résultat attendu, on effectue un jump sur $$endif$$ sinon on avance vers le label $$then$$.
\subsection{Opération de modification de la valeur de la variable}
Le compilateur produit du code à chaque fois qu'une règle le permet. Chaque ligne de code est écrit en 2 adresses. Ainsi, nous avons des expressions sémantiques pour:

\begin{itemize}
\item les opérations unaires
\item les affectations
\item les $$if$$
\item les $$goto$$
\item les labels
\end{itemize}

Comme pour chaque manipulation des commandes $$cmd$$, nous utilisons la fonction $$sprintf$$ afin d'encastrer les commandes au bon endroit. 

Finalement, lorsque que nous effectuons une opération ``basique'' (cf $$expression$$), nous recopions d'abord les opérations des deux $$unary\_expression$$ puis nous lançons l'opération relative à l'opérateur ($$mul$$, $$add$$, $$sub$$ ou $$mov$$ pour une affectation). Une fois cette action effectuée, la valeur obtenue est stockée dans l'un des deux registres des $$unary\_expression$$. Il suffit alors de récupérer $$val$$.
 
\chapter*{Conclusion}

Ce projet bien que non terminé au niveau du code, nous a tout de même permis de mieux comprendre le fonctionnement d'un compilateur et de mieux maîtriser le langage assembleur.

\end{document}
